/*---------------------------------------------------------------------------------------*
 * gms_sql.h
 *
 *  Definition about gms_sql package.
 *
 * IDENTIFICATION
 *        contrib/gms_sql/gms_sql.h
 *
 * ---------------------------------------------------------------------------------------
 */
#ifndef GMS_SQL_H
#define GMS_SQL_H


#include "catalog/pg_type.h"
#include "executor/spi.h"
#include "parser/parse_coerce.h"
#include "utils/memutils.h"
/*
 * It is used for transformation result data to form
 * generated by column_value procedure or column
 * value function.
 */
typedef struct
{
	bool		isvalid;                /* true, when this cast can be used */
        bool		without_cast;           /* true, when cast is not necessary */
	Oid		targettypid;		/* used for domains */
	Oid		array_targettypid;      /* used for array domains */
	int32		targettypmod;           /* used for strings */
	bool		typbyval;               /* used for copy result to outer memory context */
	int16		typlen;                 /* used for copy result to outer memory context */
	bool		is_array;
	Oid		funcoid;
        Oid             funcoid_typmod;
        CoercionPathType path;
        CoercionPathType path_typmod;
        FmgrInfo        finfo;
        FmgrInfo        finfo_typmod;
        FmgrInfo        finfo_out;
        FmgrInfo        finfo_in;
        Oid		typIOParam;
} CastCacheData;

/*
 * gms_sql cursor definition
 */
typedef struct
{
        int16		cid;
        char		*parsed_query;
        char		*original_query;
        unsigned int	nvariables;
        int		max_colpos;
        List		*variables;
        List		*columns;
        char		cursorname[32];
        Portal		portal;			/* one shot (execute) plan */
        SPIPlanPtr      plan;
        MemoryContext	cursor_cxt;
        MemoryContext	cursor_xact_cxt;
        MemoryContext	tuples_cxt;
        MemoryContext	result_cxt;		/* short life memory context */
        HeapTuple       tuples[1000];
        TupleDesc       coltupdesc;
        TupleDesc       tupdesc;
        CastCacheData	*casts;
        uint64          processed;
        uint64          nread;
        uint64          start_read;
        bool            assigned;
        bool            executed;
        Bitmapset	*array_columns;		/* set of array columns */
        uint64          batch_rows;		/* how much rows should be fetched to fill target arrays */
} CursorData;

typedef struct GmssqlContext
{
    MemoryContext	gms_sql_cxt = NULL;
    CursorData		*gms_sql_cursors = NULL;
}GmssqlContext;

/*
 * bind variable data
 */
typedef struct
{
    char       *refname;
    int            position;

    Datum        value;

    Oid            typoid;
    bool        typbyval;
    int16        typlen;

    bool        isnull;
    unsigned int varno;        /* number of assigned placeholder of parsed query */
    bool        is_array;      /* true, when a value is assigned via bind_array */
    Oid            typelemid;  /* Oid of element of a array */
    bool        typelembyval;
    int16        typelemlen;
    int            index1;
    int            index2;
} VariableData;

/*
 * Query result column definition
 */
typedef struct
{
    int            position;

    Oid            typoid;
    bool        typbyval;
    int16        typlen;
    int32        typmod;
    bool        typisstr;
    Oid            typarrayoid;        /* oid of requested array output value */
    uint64        rowcount;            /* maximal rows of requested array */
    int            index1;             /* output array should be rewrited from this index */
} ColumnData;

typedef enum
{
    TOKEN_SPACES,
    TOKEN_COMMENT,
    TOKEN_NUMBER,
    TOKEN_BIND_VAR,
    TOKEN_STR,
    TOKEN_EXT_STR,
    TOKEN_DOLAR_STR,
    TOKEN_IDENTIF,
    TOKEN_QIDENTIF,
    TOKEN_DOUBLE_COLON,
    TOKEN_OTHER,
    TOKEN_NONE
} ofTokenType;

/* from gms_sql.cpp */
extern "C"  Datum gms_sql_is_open(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_open_cursor(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_close_cursor(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_parse(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_bind_variable(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_bind_variable_f(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_bind_array_3(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_bind_array_5(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_define_column(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_define_array(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_execute(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_fetch_rows(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_execute_and_fetch(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_column_value(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_column_value_f(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_last_row_count(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_describe_columns(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_describe_columns_f(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_debug_cursor(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_return_result(PG_FUNCTION_ARGS);
extern "C"  Datum gms_sql_return_result_i(PG_FUNCTION_ARGS);
extern "C" void set_extension_index(uint32 index);
extern "C" void init_session_vars(void);

#endif
